package com.et114.modules.extend.acegi;

import org.acegisecurity.Authentication;
import org.acegisecurity.AuthenticationException;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.acegisecurity.userdetails.UserDetails;
import org.springframework.util.Assert;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.et114.components.acegi.Constants;
import com.et114.components.acegi.intercept.web.ILoginSuccessfulAuthentication;
import com.et114.components.acegi.intercept.web.ValidCodeAuthenticationProcessingFilter;
import com.et114.modules.org.services.UserManager;
import com.et114.modules.org.utility.SessionUserInfo;

import java.util.Date;
import java.util.Iterator;
import java.util.List;



/**
 * @author guanhw
 */
public class AwUserAuthenticationProcessingFilter extends ValidCodeAuthenticationProcessingFilter {
	private UserManager	userManager	= null;
	private List		afterSuccessAuths;
	private long deleym = 2592000000L ; 
	private boolean isCheckPass = false ; 
	private String checkedPass = "toCheckPass" ;
	
	private AwAuthenticationManager awAuthenticationManager ; 
	
	public void setUserManager ( UserManager userManager ) {
		this.userManager = userManager;
	}
	
	public void setAfterSuccessAuths ( List afterSuccessAuths ) {
		if ( afterSuccessAuths != null ) {
			// Assert.notEmpty( initBeans );
			Iterator iter = afterSuccessAuths.iterator ( );
			while (iter.hasNext ( )) {
				Object currentObject = iter.next ( );
				Assert.isInstanceOf (
								ILoginSuccessfulAuthentication.class ,
								currentObject ,
								"ILoginSuccessfulAuthentication "
										+ currentObject.getClass ( ).getName ( )
										+ " must implement ILoginSuccessfulAuthentication" );
			}
		}
		this.afterSuccessAuths = afterSuccessAuths;
	}
	
	protected void onSuccessfulAuthentication ( HttpServletRequest request ,
			HttpServletResponse response , Authentication authResult ) {
		HttpSession httpSession = null;
		try {
			httpSession = request.getSession ( false );
		} catch ( IllegalStateException ignored ) {
		}
		if ( httpSession != null ) {
				if ( authResult != null && authResult.getPrincipal ( ) instanceof UserDetails ) {
					try {
						// after syc
						logger.info ( "init login afterSuccessAuths beans start ..." );
						if ( afterSuccessAuths != null ) {
							for ( java.util.Iterator iter = afterSuccessAuths
									.iterator ( ) ; iter.hasNext ( ) ; ) {
								ILoginSuccessfulAuthentication la = ( ILoginSuccessfulAuthentication ) iter
										.next ( );
								la.afterSuccessfulAuthentication ( httpSession );
							}
						}
						logger.info ( "init login afterSuccessAuths beans end ..." );
					} catch ( Exception e ) {
						logger.error ( e.getMessage ( ) , e );
					}
				}
		}
	}
	
	public Authentication attemptAuthentication (	HttpServletRequest httpServletRequest ) throws AuthenticationException {
		HttpSession httpSession = null;
		try {
			httpSession = httpServletRequest.getSession ( false ) ;
		} catch ( IllegalStateException ignored ) {
		}		
		//检查是否通过用户密码登录
		if ( obtainUsername( httpServletRequest ) == null ) return null ;
		
		

		Authentication authResult = attemptAuthentication1 ( httpServletRequest );
		if ( authResult != null && authResult.getPrincipal ( ) instanceof UserDetails ) {
			UserDetails ud = ( UserDetails ) authResult.getPrincipal ( );
			String password = ud.getPassword ( );
			String loginName = ud.getUsername ( );

			SessionUserInfo userInfo = userManager.getSessionUserInfoByLoginNameAndPassword ( loginName , password );
			userInfo.setSessionID ( httpSession.getId ( ) );
			
			String authType = httpServletRequest.getParameter ( AwConst.SSO_LOGIN_TYPE_PARAM ) ; 
			if ( authType != null ) httpSession.setAttribute ( AwConst.SSO_LOGIN_TYPE_PARAM , authType ) ;
			
			String to = httpServletRequest.getParameter ( ACEGI_SECURITY_SUCCESS_URL_METHOD ) ; 

			if ( isCheckPass  ) {
				userInfo.setCheckPass ( isCheckPass ) ; 
				Date date = userInfo.getLastModPassTime ( ) ; 
				if ( date == null  ) {
					setDefaultTargetUrl (  ( ( String  )getTargetUrls(  ).get ( checkedPass )  ) ) ; 
					if ( to != null && !"".equals ( to ) ) 
						userInfo.setCheckedDefaultTargetUrl (  ( ( String  )getTargetUrls(  ).get ( to )  ) ) ;	

				}
					
				else {
					long cut = System.currentTimeMillis ( ) ; 
					long lastTime = date.getTime ( ) ; 
					if ( cut - lastTime >= deleym ) {
						setDefaultTargetUrl (  ( ( String  )getTargetUrls(  ).get ( checkedPass )  ) ) ; 
						if ( to != null && !"".equals ( to ) ) 
							userInfo.setCheckedDefaultTargetUrl (  ( ( String  )getTargetUrls(  ).get ( to )  ) ) ;	
					}
						
					else {
						userInfo.setCheckPassState ( true ) ;
						if ( to != null && !"".equals ( to ) ) 
							setDefaultTargetUrl (  ( ( String  )getTargetUrls(  ).get ( to )  ) ) ;	
					}
				}	
				
			}
			else {
				if ( to != null && !"".equals ( to ) ) 
					setDefaultTargetUrl(  ( ( String  )getTargetUrls(  ).get ( to )  ) ) ;
				
			}
			//check pass	
			httpSession.setAttribute ( Constants.SESSION_CURRENT_USER_KEY , userInfo );
		}
		return authResult ;
	}

	
	public Authentication attemptAuthentication1 (	HttpServletRequest httpServletRequest ) throws AuthenticationException {
		doValidCode( httpServletRequest ) ; 
		String username = obtainUsername( httpServletRequest );
		String password = obtainPassword( httpServletRequest );

		if ( username == null ) {
			username = "";
		}

		if ( password == null ) {
			password = "";
		}

		username = username.trim();
		
		UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken( username, password );

		// Place the last username attempted into HttpSession for views
		httpServletRequest.getSession().setAttribute( ACEGI_SECURITY_LAST_USERNAME_KEY , username );

		// Allow subclasses to set the "details" property
		setDetails( httpServletRequest, authRequest );
		String authType = httpServletRequest.getParameter ( AwConst.SSO_LOGIN_TYPE_PARAM ) ; 
		if ( authType != null
				&& ! "".equals ( authType.trim ( ) )
				&& ( AwConst.SSO_LOGIN_TYPE_CODE.equals ( authType ) || AwConst.SSO_LOGIN_TYPE_LG
						.equals ( authType ) ) ) {
			return awAuthenticationManager.authenticate( authRequest , authType );
		}
		
		return getAuthenticationManager().authenticate( authRequest );
	}	

	public long getDeleym ( ) {
		return deleym;
	}

	public void setDeleym ( long deleym ) {
		this.deleym = deleym;
	}

	public boolean isCheckPass ( ) {
		return isCheckPass;
	}

	public void setIsCheckPass ( boolean isCheckPass ) {
		this.isCheckPass = isCheckPass;
	}

	public AwAuthenticationManager getAwAuthenticationManager ( ) {
		return awAuthenticationManager;
	}

	public void setAwAuthenticationManager (
			AwAuthenticationManager awAuthenticationManager ) {
		this.awAuthenticationManager = awAuthenticationManager;
	}

}
